/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-04-27
*/
package com.rzico.account.service;

import com.alibaba.fastjson.JSON;
import com.rzico.account.entity.*;
import com.rzico.account.mapper.PaymentMapper;
import com.rzico.account.mapper.RefundsMapper;
import com.rzico.account.mapper.TransferMapper;
import com.rzico.account.model.Attach;
import com.rzico.base.BaseMapper;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.account.mapper.DepositMapper;
import com.rzico.basics.entity.Enterprise;
import com.rzico.basics.entity.Member;
import com.rzico.basics.mapper.MemberMapper;
import com.rzico.basics.service.EnterpriseService;
import com.rzico.basics.service.MsgService;
import com.rzico.core.entity.SysMch;
import com.rzico.core.entity.SysPlugin;
import com.rzico.core.entity.SysUser;
import com.rzico.core.plugin.PaymentPlugin;
import com.rzico.core.plugin.TransferPlugin;
import com.rzico.core.service.SysMchService;
import com.rzico.core.service.SysPluginService;
import com.rzico.core.service.SysUserService;
import com.rzico.exception.CustomException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <pre>
 * 钱包账单业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
public class DepositService extends BaseServiceImpl<Deposit, String> {

    @Autowired
    private DepositMapper depositMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired @Lazy
    private SysPluginService sysPluginService;

    @Autowired @Lazy
    private RefundsMapper refundsMapper;
    @Autowired @Lazy
    private PaymentMapper paymentMapper;

    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired @Lazy
    private TransferMapper transferMapper;

    @Autowired
    private SysMchService sysMchService;

    @Autowired @Lazy
    private MsgService msgService;

    @Autowired @Lazy
    private SysUserService sysUserService;


    @Autowired @Lazy
    private TransferService transferService;

    @Override
    public BaseMapper<Deposit, String> getMapper() {
        return depositMapper;
    }

    //付款
    @Transactional(rollbackFor = Exception.class)
    public void payment(Payment payment) {
        if (!payment.getStatus().equals(Payment.STATUS_WAITING)) {
            throw new CustomException("不是待付款状态");
        }
        payment.setStatus(Payment.STATUS_SUCCESS);
        payment.setPaymentDate(new Date());
        payment.setPaymentPluginId("balancePayPlugin");
        payment.setPaymentPluginName("钱包支付");
        paymentMapper.updateByPrimaryKeySelective(payment);

        Member member = memberMapper.selectByPrimaryKey(payment.getMemberId());
        if (member.calculateAvailableBalance().compareTo(payment.getAmount())<0) {
            throw new CustomException("钱包余额不足");
        }
        Map<String,Object> updateParams = new HashMap<>();
        updateParams.put("id",payment.getMemberId());
        updateParams.put("value",payment.getAmount());
        memberMapper.decBalance(updateParams);
        //更新重新读取余额
        member = memberMapper.selectByPrimaryKey(payment.getMemberId());

        if (member.getBalance().compareTo(BigDecimal.ZERO)<0) {
            throw new CustomException("钱包余额不足");
        }

        Deposit deposit = new Deposit();
        deposit.setBalance(member.getBalance());
        deposit.setDebit(payment.getAmount());
        deposit.setCredit(BigDecimal.ZERO);
        deposit.setCreateDate(new Date());
        deposit.setModifyDate(new Date());
        deposit.setDeleted(false);
        deposit.setEnterpriseId(payment.getEnterpriseId());
        deposit.setMemberId(payment.getMemberId());
        deposit.setMemo(payment.getMemo());
        deposit.setPaymentId(payment.getId());
        deposit.setType(1);
        deposit.setDeleted(false);
        deposit.setOrderId(payment.getOrderId());
        deposit.setOrderType(payment.getOrderType());
        super.insertUseGeneratedKeys(deposit);


        Map<String,Object> content = new HashMap<>();

        content.put("title", "付款成功-钱包");

        content.put("memo",payment.getMemo());
        content.put("amount",payment.getAmount());
        content.put("balance",deposit.getBalance());
        content.put("type",1);
        msgService.sendNotity(member,"msg-account",content.get("title").toString(), JSON.toJSONString(content),null);


    }

    //退款
    @Transactional(rollbackFor = Exception.class)
    public void refunds(Refunds refunds) {
        if (!refunds.getStatus().equals(Refunds.STATUS_WAITING)) {
            throw new CustomException("不是待退款状态");
        }
        refunds.setStatus(Refunds.STATUS_REFUNDED);
        refunds.setRefundsDate(new Date());
        refunds.setPaymentPluginId("balancePayPlugin");
        refunds.setPaymentPluginName("钱包支付");
        refundsMapper.updateByPrimaryKeySelective(refunds);

//        if (refunds.getPaymentId()!=null) {
//            Payment payment = paymentMapper.selectByPrimaryKey(refunds.getPaymentId());
//            if (payment==null) {
//                throw new CustomException("无效付款单号");
//            }
//            payment.setStatus(Payment.STATUS_REFUND_SUCCESS);
//            paymentMapper.updateByPrimaryKeySelective(payment);
//        }
//

        Map<String,Object> updateParams = new HashMap<>();
        updateParams.put("id",refunds.getMemberId());
        updateParams.put("value",refunds.getAmount());
        memberMapper.decBalance(updateParams);
        //更新重新读取余额
        Member member = memberMapper.selectByPrimaryKey(refunds.getMemberId());

        Deposit deposit = new Deposit();
        deposit.setBalance(member.getBalance());
        deposit.setDebit(BigDecimal.ZERO);
        deposit.setCredit(refunds.getAmount());
        deposit.setCreateDate(new Date());
        deposit.setModifyDate(new Date());
        deposit.setDeleted(false);
        deposit.setEnterpriseId(refunds.getEnterpriseId());
        deposit.setMemberId(refunds.getMemberId());
        deposit.setMemo(refunds.getMemo());
        deposit.setPaymentId(refunds.getId());
        deposit.setType(2);
        deposit.setDeleted(false);
        deposit.setOrderId(refunds.getOrderId());
        deposit.setOrderType(refunds.getOrderType());
        super.insertUseGeneratedKeys(deposit);



        Map<String,Object> content = new HashMap<>();

        content.put("title", "退款成功-钱包");

        content.put("memo",refunds.getMemo());
        content.put("amount",refunds.getAmount());
        content.put("balance",deposit.getBalance());
        content.put("type",1);
        msgService.sendNotity(member,"msg-account",content.get("title").toString(), JSON.toJSONString(content),null);

    }

    public BigDecimal calculate(Enterprise enterprise,BigDecimal amount) {
        return BigDecimal.ZERO;
    }

    //提现
    @Transactional(rollbackFor = Exception.class)
    public Deposit transfer(Member member,BigDecimal amount,String paymentPluginId,String sn) {
        Enterprise enterprise = enterpriseService.selectByPrimaryKey(member.getEnterpriseId());
        if (member.calculateAvailableBalance().compareTo(amount)<0) {
            throw new CustomException("可提现余额不足");
        }

        BigDecimal fee = calculate(enterprise,amount);
        Map<String,Object> params = new HashMap<>();
        params.put("id",member.getId());
        params.put("value",amount);
        memberMapper.decBalance(params);

        member = memberMapper.selectByPrimaryKey(member.getId());

        if (member.getBalance().compareTo(BigDecimal.ZERO)<0) {
            throw new CustomException("可提现余额不足");
        }

        Deposit deposit = new Deposit();
        deposit.setCreateDate(new Date());
        deposit.setModifyDate(new Date());
        deposit.setBalance(member.getBalance());
        deposit.setDebit(amount);
        deposit.setCredit(BigDecimal.ZERO);
        deposit.setDeleted(false);
        deposit.setEnterpriseId(member.getEnterpriseId());
        deposit.setMemberId(member.getId());
        if ("weixinWalletPlugin".equals(paymentPluginId)) {
            deposit.setMemo("提现到-微信零钱");
        } else {
            deposit.setMemo("提现到-绑定银行卡");
        }
        deposit.setType(3);
        deposit.setDeleted(false);
        super.insertUseGeneratedKeys(deposit);

        //生成付款单
        Transfer transfer = new Transfer();
        transfer.setMemberId(member.getId());
        transfer.setSn(sn);
        transfer.setAmount(amount);
        transfer.setFee(fee);
        transfer.setCreateDate(new Date());
        transfer.setModifyDate(transfer.getCreateDate());
        transfer.setDeleted(false);
        transfer.setPaymentPluginId(paymentPluginId);
        if ("weixinWalletPlugin".equals(paymentPluginId)) {
            transfer.setPaymentPluginName("付款到微信零钱");
            deposit.setMemo("提现到微信零钱");
        } else {
            //获取绑定银卡行信息
            deposit.setMemo("提现到银行卡");
            transfer.setPaymentPluginName("付款到银行卡");
        }

        SysMch sysMch = sysMchService.selectByPrimaryKey(enterprise.getMchId());
        if (sysMch.getMchType().equals(2)) {
            //特约商户,服务商代收 status
            enterprise = enterpriseService.findByMch(sysMch.getIsvId());
        }

        transfer.setEnterpriseId(enterprise.getId());
        transfer.setMemo(deposit.getMemo());
        transfer.setStatus(0);
        transfer.setType(3);
        transferMapper.insertUseGeneratedKeys(transfer);

        //微信零钱秒到，自动发起付款申请
        if ("weixinWalletPlugin".equals(paymentPluginId)) {
            transferService.submit(transfer,paymentPluginId);
        }
        return deposit;

    }

    //入账
    @Transactional(rollbackFor = Exception.class)
    public void addBalance(Long memberId,BigDecimal value,Integer type,String memo,Integer orderType,Long orderId) {

        Member member = memberMapper.selectByPrimaryKey(memberId);

        Map<String,Object> updateParams = new HashMap<>();
        updateParams.put("id",memberId);
        updateParams.put("value",value);
        memberMapper.addBalance(updateParams);

        //更新重新读取余额
        member = memberMapper.selectByPrimaryKey(memberId);

        if (member.getBalance().compareTo(BigDecimal.ZERO)<0) {
            throw new CustomException("账户余额不足");
        }

        Deposit deposit = new Deposit();
        deposit.setBalance(member.getBalance());
        deposit.setDebit(BigDecimal.ZERO);
        deposit.setCredit(value);
        deposit.setCreateDate(new Date());
        deposit.setModifyDate(new Date());
        deposit.setDeleted(false);
        deposit.setEnterpriseId(member.getEnterpriseId());
        deposit.setMemberId(memberId);
        deposit.setMemo(memo);
        deposit.setType(type);
        deposit.setDeleted(false);
        deposit.setOrderType(orderType);
        deposit.setOrderId(orderId);
        super.insertUseGeneratedKeys(deposit);

    }

    //出账
    @Transactional(rollbackFor = Exception.class)
    public void decBalance(Long memberId,BigDecimal value,Integer type,String memo,Integer orderType,Long orderId) {

        Member member = memberMapper.selectByPrimaryKey(memberId);

        Map<String,Object> updateParams = new HashMap<>();
        updateParams.put("id",memberId);
        updateParams.put("value",value);
        memberMapper.decBalance(updateParams);

        //更新重新读取余额
        member = memberMapper.selectByPrimaryKey(memberId);

        if (member.getBalance().compareTo(BigDecimal.ZERO)<0) {
            throw new CustomException("账户余额不足");
        }

        Deposit deposit = new Deposit();
        deposit.setBalance(member.getBalance());
        deposit.setDebit(value);
        deposit.setCredit(BigDecimal.ZERO);
        deposit.setCreateDate(new Date());
        deposit.setModifyDate(new Date());
        deposit.setDeleted(false);
        deposit.setEnterpriseId(member.getEnterpriseId());
        deposit.setMemberId(memberId);
        deposit.setMemo(memo);
        deposit.setType(type);
        deposit.setDeleted(false);
        deposit.setOrderType(orderType);
        deposit.setOrderId(orderId);
        super.insertUseGeneratedKeys(deposit);

    }


}
